package com.zf.until_now;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
 * jdk21新特性正式版：
 * - record 类的 instanceof 增强（模式匹配增强），正式推出
 * - switch 类型匹配，正式推出
 * - 虚拟线程，正式推出
 * - 有序集合，正式推出
 * - StringBuilder和StringBuffer新增了一个repeat方法，正式推出
 */
public class Jdk21Release {
    public static void main(String[] args) {
        // recordInstanceof();
        // System.out.println("============");
        // testSwitchInstanceof(1);
        // System.out.println("============");
        // testSortedCollection();
        // System.out.println("============");
        // testStringRepeat();
        // System.out.println("============");
        testVirtualThread();
    }


    record Dog(String name, Integer age) {
    }

    /**
     * record 的 instanceof 增强
     */
    public static void recordInstanceof() {
        Object obj = new Dog("德牧", 2);

        // 普通
        if (obj instanceof Dog dog) {
            System.out.println(dog.name());
            System.out.println(dog.age());
        }

        System.out.println("-----------");
        // 增强
        if (obj instanceof Dog(String name, Integer age)) {
            System.out.println(name);
            System.out.println(age);
        }

    }

    /**
     * switch 新增类型匹配，可以实现 "obj instanceof Integer i" 的效果
     */
    public static void testSwitchInstanceof(Object obj) {
        System.out.println("odl------");
        if (obj instanceof Integer i) {
            System.out.println(i);
        } else if (obj instanceof Double d) {
            System.out.println(d);
        } else if (obj instanceof String s) {
            System.out.println(s);
        } else {
            System.out.println("其他类型");
        }

        System.out.println("new-----------");
        // switch 新增类型匹配，可以实现 "obj instanceof Integer i" 的效果
        // 新的 switch 支持 null 判断
        String res = switch (obj) {
            case null -> "null 类型";
            case Integer i -> {
                System.out.println("Integer类型");
                // 作为返回值
                yield i.toString();
            }
            case Double d -> {
                System.out.println("浮点");
                yield d.toString();
            }
            case String s -> {
                System.out.println("字符串类型");
                yield s;
            }
            default -> "其他类型";
        };
        System.out.println(res);

        //支持等值判断和类型匹配混用
        System.out.println("new2---------");
        String txt = "你好";
        switch (txt) {
            case null -> System.out.println("空");
            case "你" -> System.out.println("你");
            case String s -> System.out.println("字符串");
        }

        // switch模式匹配如果是密封类则，不需要default
        S s = new A();
        switch (s) {
            case A a -> System.out.println(a);
            case B b -> System.out.println(b);
        }
    }

    sealed interface S permits A, B {
    }

    static final class A implements S {
    }

    static final class B implements S {
    }

    /**
     * 虚拟线程：
     * 注意：虚拟线程只是增加程序的吞吐量，并不能提高线程的执行速度。但是 多个虚拟线程的总执行时间 会比 直接使用多线程的总时间 要少很多
     */
    public static void testVirtualThread() {
        // 1、Thread.startVirtualThread启动一个虚拟线程
        Runnable task = () -> {
            System.out.println(Thread.currentThread().getName() + ": v-t");
        };

        Thread.startVirtualThread(task);

        // 2、使用 Thread.ofVirtual()
        Thread.Builder.OfVirtual ofVirtual = Thread.ofVirtual();
        ofVirtual.name("虚拟线程");
        ofVirtual.start(task);
        ofVirtual.start(task);

        long start = System.currentTimeMillis();
        // 3、使用线程池创建虚拟线程
        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
        // 创建10万个虚拟线程，每个虚拟线程休眠1s
        for (int i = 0; i < 100000; i++) {
            final int a = i;
            executor.submit(() -> {
                try {
                    Thread.sleep(1000);
                    // System.out.println("序号：" + a);
                } catch (InterruptedException ignored) {
                }
                return a;
            });
        }
        // 关闭线程池，等待已经提交的任务全部执行结束
        executor.close();
        long end = System.currentTimeMillis();
        System.out.println(end - start);

        // 4、使用虚拟线程工厂
        ThreadFactory virtualThreadFactory = Thread.ofVirtual()
                .name("虚拟线程工厂", 0)
                .factory();
        Thread factoryThread1 = virtualThreadFactory.newThread(task);
        Thread factoryThread2 = virtualThreadFactory.newThread(task);
        factoryThread1.start();
        factoryThread2.start();

    }

    /**
     * 有序集合新增获取、移除、新增第一个和最后一个API，逆序集合的API
     */
    public static void testSortedCollection() {
        List<Integer> list = new ArrayList<>(List.of(1, 2, 3));
        // 获取集合的第一个和最后一个
        Integer listFirst = list.getFirst();
        Integer listLast = list.getLast();
        System.out.printf("list first: %d, last: %d\n", listFirst, listLast);
        // 在开始和结尾加一个
        list.addFirst(-1);
        list.addLast(4);
        // 反转集合
        List<Integer> reversedList = list.reversed();
        System.out.println("add list: " + list);
        System.out.println("list reverse: " + reversedList);
        // 移除第一个和最后一个
        list.removeFirst();
        list.removeLast();
        System.out.println("remove list: " + list);

        LinkedHashSet<Integer> set = LinkedHashSet.newLinkedHashSet(3);
        set.add(1);
        set.add(2);
        set.add(3);
        Integer setFirst = set.getFirst();
        Integer setLast = set.getLast();
        System.out.printf("set first: %d, last: %d\n", setFirst, setLast);
        // 在开始和结尾加一个
        set.addFirst(-1);
        set.addLast(4);
        // 反转集合
        Set<Integer> reversedSet = set.reversed();
        System.out.println("add set: " + set);
        System.out.println("set reverse: " + reversedSet);
        // 移除第一个和最后一个
        set.removeFirst();
        set.removeLast();
        System.out.println("remove set: " + set);
    }

    /**
     * StringBuilder和StringBuffer新增了一个repeat方法，正式推出
     */
    public static void testStringRepeat() {
        StringBuilder sb = new StringBuilder();
        sb.append("111");
        // repeat将一个字符串重复指定次数后，加到StringBuilder中
        sb.repeat("*$", 10);
        System.out.println(sb.toString());
    }

}
